package com.wgke.bluetooth.view;


import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class PressureMatrixRenderer2 implements GLSurfaceView.Renderer {
    public static int WIDTH = 200;
    public static int HEIGHT = 120;
    private static final float CONTENT_ASPECT = (float) WIDTH / HEIGHT;

    // 矩阵
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];
    private final float[] mModelMatrix = new float[16];
    private final float[] mMVPMatrix = new float[16];
    private float mTransitionProgress = 1.0f;

    // 数据
    private float[] mPressureData = new float[WIDTH * HEIGHT];
    private FloatBuffer mVertexBuffer;
    private FloatBuffer mColorBuffer;

    // 渲染参数
    private int mProgram;
    private float mPointSize = 4.0f;
    private float mAspectRatio = 1.0f;

    // 3D参数（保持原有3D效果）
    private float TILT_ANGLE = 18.0f;
    private static final float HEIGHT_SCALE = 0.5f;
    private static final float CAMERA_Z = 3.0f;
    private static final float FOV = 45.0f; // 新增：控制3D视野
    private static final float NEAR_PLANE = 1.0f;
    private static final float FAR_PLANE = 20.0f;

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        initShaders();
        initTestData();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        mAspectRatio = (float) width / height;

        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, CAMERA_Z, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        updateProjectionMatrix();
        updateModelMatrix();
    }

    // 核心修改：2D模式匹配3D宽度
    private void updateProjectionMatrix() {
        // 计算3D模式下实际显示的宽度（保持原有3D大小）
        float visible3DWidth = 2 * CAMERA_Z * (float) Math.tan(Math.toRadians(FOV / 2));

        // 2D模式：使用3D的可见宽度作为正交投影范围
        float orthoHeight = visible3DWidth / CONTENT_ASPECT;
        Matrix.orthoM(mProjectionMatrix, 0, -visible3DWidth / 2, visible3DWidth / 2, -orthoHeight / 2, orthoHeight / 2, NEAR_PLANE, FAR_PLANE);

    }

    private void updateModelMatrix() {
        Matrix.setIdentityM(mModelMatrix, 0);
        Matrix.rotateM(mModelMatrix, 0, 0f, 1.0f, 0.0f, 0.0f);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        // 过渡动画

        updateProjectionMatrix();
        updateModelMatrix();
        // 计算MVP矩阵
        Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

        drawPressureMatrix();
    }

    private void initShaders() {
        String vertexShaderCode = "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "attribute vec4 vColor;" + "varying vec4 fColor;" + "uniform float uPointSize;" + "void main() {" + "  gl_Position = uMVPMatrix * vPosition;" + "  fColor = vColor;" + "  gl_PointSize = uPointSize;" + "}";

        String fragmentShaderCode = "precision mediump float;" + "varying vec4 fColor;" + "void main() {" + "  gl_FragColor = fColor;" + "}";

        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, vertexShader);
        GLES20.glAttachShader(mProgram, fragmentShader);
        GLES20.glLinkProgram(mProgram);
    }

    private int loadShader(int type, String shaderCode) {
        int shader = GLES20.glCreateShader(type);
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);
        return shader;
    }

    public float[][] initTestData() {
        // 初始化测试数据（中心高压区域）
        for (int i = 0; i < WIDTH * HEIGHT; i++) {
            mPressureData[i] = 0.0f;
        }
        int centerX = WIDTH / 2;
        int centerY = HEIGHT / 2;
        return initTestData(centerX, centerY);
    }

    public float[][] initTestData(int centerX, int centerY) {
        int maxRadius = Math.min(centerX, centerY) - 5;
        Random random = new Random();
        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                float dist = (float) Math.sqrt(Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2));
                if (dist < maxRadius) {
                    float baseValue = 70.0f + random.nextFloat() * 30.0f;
                    float normalizedDist = dist / maxRadius;
                    float attenuation = (float) Math.pow(1 - normalizedDist, 2);
                    mPressureData[y * WIDTH + x] = baseValue * attenuation;
                    mPressureData[y * WIDTH + x] += (random.nextFloat() - 0.5f) * 10.0f;
                    mPressureData[y * WIDTH + x] = Math.max(0, Math.min(100, mPressureData[y * WIDTH + x]));
                }
            }
        }
        float[][] pressureData2D = new float[HEIGHT][WIDTH];
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                pressureData2D[y][x] = mPressureData[y * WIDTH + x];
            }
        }
        return pressureData2D;
    }

    private void drawPressureMatrix() {
        float[] vertices = new float[WIDTH * HEIGHT * 3];
        float[] colors = new float[WIDTH * HEIGHT * 4];

        // 计算3D模式下的实际显示宽度（用于统一缩放）
        float visible3DWidth = 2 * CAMERA_Z * (float) Math.tan(Math.toRadians(FOV / 2));
        float xScale = visible3DWidth / WIDTH;
        float yScale = xScale / CONTENT_ASPECT;

        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                int index = y * WIDTH + x;
                float pressure = mPressureData[index];

                // 统一坐标计算（2D/3D使用相同的基准宽度）
                float baseX = (x - WIDTH / 2) * xScale;
                float baseY = (y - HEIGHT / 2) * yScale;


                vertices[index * 3] = baseX;
                vertices[index * 3 + 1] = baseY;
                vertices[index * 3 + 2] = 0.0f;

                // 颜色计算（保持不变）
                if (pressure <= 0.1f) {
                    colors[index * 4] = 0.0f;
                    colors[index * 4 + 1] = 0.0f;
                    colors[index * 4 + 2] = 0.3f;
                    colors[index * 4 + 3] = 1.0f;
                } else if (pressure < 10) {
                    colors[index * 4] = 0.0f;
                    colors[index * 4 + 1] = 0.0f;
                    colors[index * 4 + 2] = 1.0f;
                    colors[index * 4 + 3] = 1.0f;
                } else if (pressure < 50) {
                    float t = (pressure - 10) / 40.0f;
                    colors[index * 4] = 0.0f;
                    colors[index * 4 + 1] = t;
                    colors[index * 4 + 2] = 1.0f - t;
                    colors[index * 4 + 3] = 1.0f;
                } else if (pressure < 85) {
                    float t = (pressure - 50) / 35.0f;
                    colors[index * 4] = t;
                    colors[index * 4 + 1] = 1.0f;
                    colors[index * 4 + 2] = 0.0f;
                    colors[index * 4 + 3] = 1.0f;
                } else {
                    float t = (pressure - 85) / 15.0f;
                    colors[index * 4] = 1.0f;
                    colors[index * 4 + 1] = 1.0f - t;
                    colors[index * 4 + 2] = 0.0f;
                    colors[index * 4 + 3] = 1.0f;
                }
            }
        }

        // 准备缓冲区
        ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        mVertexBuffer = bb.asFloatBuffer();
        mVertexBuffer.put(vertices);
        mVertexBuffer.position(0);

        ByteBuffer cb = ByteBuffer.allocateDirect(colors.length * 4);
        cb.order(ByteOrder.nativeOrder());
        mColorBuffer = cb.asFloatBuffer();
        mColorBuffer.put(colors);
        mColorBuffer.position(0);

        // 绘制
        GLES20.glUseProgram(mProgram);

        int positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        int colorHandle = GLES20.glGetAttribLocation(mProgram, "vColor");
        int mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        int pointSizeHandle = GLES20.glGetUniformLocation(mProgram, "uPointSize");

        GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mMVPMatrix, 0);
        GLES20.glUniform1f(pointSizeHandle, mPointSize);

        GLES20.glEnableVertexAttribArray(positionHandle);
        GLES20.glEnableVertexAttribArray(colorHandle);

        GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, mVertexBuffer);
        GLES20.glVertexAttribPointer(colorHandle, 4, GLES20.GL_FLOAT, false, 0, mColorBuffer);

        GLES20.glDrawArrays(GLES20.GL_POINTS, 0, WIDTH * HEIGHT);

        GLES20.glDisableVertexAttribArray(positionHandle);
        GLES20.glDisableVertexAttribArray(colorHandle);
    }


    public void set3DMode(boolean is3D) {
        this.TILT_ANGLE = is3D ? 18.0f : 0.0f;
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    }

}